POGLAVLJE 2. IZVORNI TIPOVI PODATAKA
Poglavlje 2. Izvorni tipovi podataka “Wonder is the foundation of all philosophy, inquiry its progress, ignorance its end.” ''-Michel de Montaigne'' 2.1 Zaronimo Tipovi podataka. Ostavite sa strane svoj prvi Python program samo na minut i hajde da pričamo o tipovima podataka. U Python-u, svaka vrednost ima svoj tip podatka, ali Vi ne morate da deklarišete tip podataka varijabli. Kako to funkcioniše? Na osnovu svakog originalnog zadatka varijable, Python shvata koji je to tip i interno ga prati. Python ima mnogo izvornih tipova podataka. Evo onih bitnih: 1. Booleans – ili su true (tačni) ili su false (netačni) 2. Numbers – mogu biti celobrojna vrednost (1 i 2), zapis u pokretnom zarezu (1.1 i 1.2), razlomci (1/2 i 2/3) ili čak kompleksni brojevi. 3. Strings – oni su sekvence Unicode karaktera, na primer HTML dokument. 4. Bytes and byte arrays – bitovi i nizovi bitova, na primer slika u JPEG formatu 5. Lists – liste su uređene sekvence vrednosti 6. Tuples – određene, nepromenljive sekvence vrednosti 7. Sets – neuređeni skupovi vrednosti 8. Dictionaries – neodređeni skupovi key-value parova Naravno, postoji više tipova od ovoga. Sve je objekat u Python-u, znači imamo tipove kao što su moduli, funkcije, klase, metode, fajlovi pa čak i već sastavljeni kod. Već ste videli neke od ovih: moduli imaju imena, funkcije imaju docstrings, itd. Učićete o klasama u Classes & Iterators, i o fajlovima u Files. Stringovi i bajtovi su sami po sebi dovoljno komplikovani zbog čega imaju zasebna poglavlja. Hajde da pogledamo prvo druge. 2.2 Booleans ' Booleans sui ili True ili False. Python ima dve konstante, pametno nazvane True i False, koje mogu biti iskoriščene da Booleans-ima direktno dodele vredosti. Izrazi se takodje mogu proceniti na Boolean vrednost. Ova “mesta” se zovu Boolean contexts. Virtuelno, možete iskoristiti bilo koji izraz u Boolean context-u i Python će da pokuša da odredi njegovu pravu vrednost. Različiti tipovi podataka imaju različita pravila o tome koje vrednosti su true, a koje false u Boolean context-u. (Ovo će imati više smisla jednom kada vidite čvrste primere kasnije u ovom poglavlju.) Na primer, uzmimo ovaj isečak iz humansize.py: if size < 0: raise ValueError(‘number must be non-negative’) size je celobrojna vrednost, 0 je celobrojna vrednost i < je numerički operator. Rezultat izraza size < 0 je uvek boolean. Možete da proverite svoje znanje u Python interactive konzoli: >>> size = 1 >>> size < 0 False >>> size = 0 >>> size < 0 False >>> size = -1 >>> size < 0 True Zbog nekih zaostavljenih problema iz Python-a 2, Booleans se mogu tretirati kao brojevi. 1 je True (tačno); 0 je False (netačno). >>> True + True 2 >>> True – False 1 >>> True * False 0 >>> True / False Traceback (most recent call last): File "", line 1, in ZeroDivisionError: int division or modulo by zero Ju, ju, ju! Ne radite to. Zaboravite da je uopste pomenuto. '''2.3. Numbers ' Numbers (brojevi) su zakon. Ima ih toliko da možete da birate. Python podržava i celobrojne brojeve i zapis u pokretnom zarezu. Ne postoji tipska deklaracija po kojoj se razlikuju; Pzthon ih razlikuje po prisutnosti ili odsutnosti decimalnog zareza. >>> type(1) ① >>> isinstance(1, int) ② True >>> 1 + 1 ③ 2 >>> 1 + 1.0 ④ 2.0 >>> type(2.0) 1. Možete koristiti type() funkicju da proverite tip bilo koje vrednosti ili promenljive. Kao što možete predpostaviti 1 je int. 2. Slično tome, možete korititi instance() funkciju da proverite da li je vredost ili promenjiva odredjenog tipa 3. Dodavanjem int-a int-u prisiljavamo int. 4. Dodavanjem int-a float-u dobijamo float. Python prisiljava int u float i vraca float kao rezultat. '''2.3.1. Prisiljavanje celobrojnih vrednosti u zapis u pokretnom zarezu I obrnuto Kao žto ste mogli da vidite, neki operatori (kao dodavanje) če “prisiliti” celobrojne vrednosti u zapis u pokretnom zarezu ako je to potrebno. To možete i Vi sami da uradite. >>> float(2) ① 2.0 >>> int(2.0) ② 2 >>> int(2.5) ③ 2 >>> int(-2.5) ④ -2 >>> 1.12345678901234567890 ⑤ 1.1234567890123457 >>> type(1000000000000000) ⑥ 1. Možete eksplicitno prisiliti int u float pozivanjem float() funkcije. 2. Bez iznenađenja, takođe možete prisiliti float u int pozivanjem int() funkcije. 3. Funkcija int() će se iseći, a ne zaokružiti. 4. Funkcija int() će iseći negativne brojeve prema 0. To je prava funkcija skraćivanja, ne funkcija koja vraca manju ili jednaku celobrojnu vrednost napomenute vrednosti ili izraza. 5. Zapis u pokretnom zarezu je tačan do 15 decimalnih mesta. 6. Celobrojne vrednosti mogu biti proizvoljno velike. ☞Python 2 je imao odvojene tipove za int i long. Int tip podataka je bio ogranicen sys.maxint, što je variralo od platforme do platforme, ali je inače bilo 223-1. Python 3 ima samo jedan tip celobrojnih vrednosti, koje se ponasaju uglavnom kao stari long tip iz Python-a 2. Pogledajte stranu 237 za više. 2.3.2. Česte numeričke operacije Možete da radite razne stvari kada su brojevi u pitanju. >>> 11 / 2 ① 5.5 >>> 11 // 2 ② 5 >>> −11 // 2 ③ −6 >>> 11.0 // 2 ④ 5.0 >>> 11 ** 2 ⑤ 121 >>> 11 % 2 ⑥ 1 1. Operacija / vrši deljenje zapisa u pokretnom zarezu. Vraća float iako su oba broja int. 2. Operacija // vrši čudno deljenje celobrojnih vrednosti. Kada je rezultat pozitivan, možete ga smatrati kao skraćivanje (ne zaokruživanje) do 0 decimalnih mesta, ali pazite se. 3. Kada deli negativne celobrojne vrednosti, // operacja zaokružuje do najbliže celobrojne vrednosti. Matematički gledano, to je zaokruživanje “nadole” jer je -6 manje od -5, ali može Vas prevariti ako ste mislili da će ga iseći na -5. 4. Operacija // neće uvek vratiti ceo broj. Ako sui brojilac ili imenilac float, i dalje će ga zaokruživati do najbliže celobrojne vrednosti, ali će prava vraćena vrednost biti float. 5. Operacija ** znaci “podignuto na stepen”. 112 je 121. 6. Operacija % daje ostatak pri deljenju celobrojnih vrednosti. 11 podeljeno sa 5 je 2 sa ostatkom 1, znaci ovde je rezultat 1. ☞U Python-u 2, operacija / je obično označavala deljenje celobrojnih vrednotsti, ali mogli ste da je naterate da se ponaša kao deljenje zapisa u pokretnom zarezu tako što biste ukljucili specijalnnu direktivu u svom kodu. U Python-u 3, operacija / uvel označava deljenje zapisa u pokretnom zarezu. Pogledajte stranu 238 za više detalja. 2.3.3. Razlomci Python nije ograničen na celobrojne vrednosti i zapise u pokretnom zarezu. On takođe može da radi svu onu luksuznu matematiku koju ste naučili u srednjoj školi I naravno odmah zaboravili. >>> import fractions ① >>> x = fractions.Fraction(1, 3) ② >>> x Fraction(1, 3) >>> x * 2 ③ Fraction(2, 3) >>> fractions.Fraction(6, 4) ④ Fraction(3, 2) >>> fractions.Fraction(0, 0) ⑤ Traceback (most recent call last): File "", line 1, in File "fractions.py", line 96, in __new__ raise ZeroDivisionError('Fraction(%s, 0)' % numerator) ZeroDivisionError: Fraction(0, 0) 1. Za početak korišćenjem razlomaka ubacite fractions moduo. 2. Kako biste definisali razlomak, napravite fraction objekat i dodajte brojilac i imenilac. 3. Možete vršiti standardne matematičke operacije sa razlomcima. Operacije vraćaju novi fraction objekat, 2 * (1/3) = (2/3) 4. Fraction objekat će automatski skratiti razlomke, (6/4) = (3/2) 5. Python ima dobar „osećaj“ da ne pravi razlomak kome je imenilac 0. 2.3.4. Trigonometrija ''' Takođe možete raditi i osnovnu trigonometriju u Python-u. >>> import math >>> math.pi ① 3.1415926535897931 >>> math.sin(math.pi / 2) ② 1.0 >>> math.tan(math.pi / 4) ③ 0.99999999999999989 1. Math moduo ima konstantu za π, odnos obima kruga i njegovog prečnika. 2. Math moduo ima sve standardne trigonometrijske funkcije uključujući sin(), cos(), tan(), i jos dosta različitih varijanti kao asin(). 3. Međutim, imajte na umu da Python nije beskonačno precizan. tan(π/4) treba da vrati 1.0, a ne 0.99999999999999989. '''2.3.5. Brojevi u Boolean context-u Možete da koristite brojeve u Boolean context-u, kao što su if iskazi. Nulte vrednosti su false, a ne-nulte vrednosti su true. >>> def is_it_true(anything): ① ... if anything: ... print("yes, it's true") ... else: ... print("no, it's false") ... >>> is_it_true(1) ② yes, it's true >>> is_it_true(-1) yes, it's true >>> is_it_true(0) no, it's false >>> is_it_true(0.1) ③ yes, it's true >>> is_it_true(0.0) no, it's false >>> import fractions >>> is_it_true(fractions.Fraction(1, 2)) ④ yes, it's true >>> is_it_true(fractions.Fraction(0, 1)) no, it's false 1. Da li ste znali da možete sami da definišete svoju sopstvene funkcije u Python-ovoj interaktivnoj konzoli? Samo pritisnite ENTER na kraju svake linije i ENTER na praznoj liniji da završite. 2. U Boolean context-u, pozitivne ili negativne celobrojne vrednosti su true. 0 je false. 3. Pozitivni i negativni zapisi u pokretnom zarezu su true; 0.0 je false. Budite oprezni sa ovim! Ako postoji cak i minijaturna greška pri zaokruživanju (nije nemoguće, kao što ste videli u prethodnom delu) onda će Python testirati 0.0000000000001 umesto 0 I vratiće true. 4. Razlomci se takođe mogu koristiti u Boolean context-u. Fraction(0,n) je false za sve vrednosti n. Svi ostali razlomci su true. 2.4 Liste Liste su Python-ovi najkorišćeniji tipovi podataka. Kada kažemo lista, možda mislite na niz čiju veličinu treba deklarisati unapred, koja može sadržati predmete istog tipa, &c. E pa ne mislite tako. Liste su mnog zabavnije od toga. ☞Lista u Python-u je kao niz u Perl 5. Perl 5, promenljive koje cuvaju nizove uvek počinju karakterom @; u Python-u, promenljive mogu biti nazvane bilo kako i Python prati tipove podataka interno. ☞Lsta u Python-u mnogo više od niza u Javi (iako se može tako koristiti ako je to ono što stvarno želite u životu). Bolja analogija bi bila ArrayList klasi koja može da drži proizvoljan objekat i da se dinamički širi kako se novi predmeti u nju dodaju. 2.4.1. Pravljenje liste Pravljenje liste je lako: koristite kockaste zagrade da obmotate zarezom odvojene vrednosti. >>> a_list = 'b', 'mpilgrim', 'z', 'example' ① >>> a_list 'b', 'mpilgrim', 'z', 'example' >>> a_list0 ② 'a' >>> a_list4 ③ 'example' >>> a_list-1 ④ 'example' >>> a_list-3 ⑤ 'mpilgrim' 1. Prvo definišete listu od pet elemenata. Imajte na umu da oni zadrzavaju svoj originalni red. To nije slučajno. Lista je uređeni skup predmeta. 2. Lista takođe može biti korišćena kao nulti zasnovan niz. Prvi predmet bilo koje ne-prazne liste je uvek a_list0. 3. Negativan indeks pristupa predmetima sa kraja liste brojeći unazad. Poslednji predmet iz ne-prazne liste je uvek a_list-1. 4. Ako Vas negativan indeks zbunjuje, zamislite to na ovaj način: a_list-n a_list- n. dakle u ovoj listi a_list-3 a_list- 3 a_list2.